package cn.tianyun.pethome.login.controller;

import cn.tianyun.pethome.basic.exception.BusinessException;
import cn.tianyun.pethome.basic.util.AjaxResult;
import cn.tianyun.pethome.basic.util.BaseConstants;
import cn.tianyun.pethome.basic.util.loginUtil.HttpClientUtils;
import cn.tianyun.pethome.basic.util.loginUtil.MD5Utils;
import cn.tianyun.pethome.basic.util.loginUtil.StrUtils;
import cn.tianyun.pethome.login.domain.LoginVo;
import cn.tianyun.pethome.login.domain.WeChatToken;
import cn.tianyun.pethome.login.domain.WxVo;
import cn.tianyun.pethome.org.domain.User;
import cn.tianyun.pethome.org.mapper.UserMapper;
import cn.tianyun.pethome.org.service.ILogininfoService;
import cn.tianyun.pethome.org.service.IUserService;
import cn.tianyun.pethome.threepart.domain.Wxuser;
import cn.tianyun.pethome.threepart.mapper.WxuserMapper;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/wechat")
public class WeChatLoginController {
    @Value("${wx.appid}")
    private String appid;
    @Value("${wx.secret}")
    private String secret;

    @Autowired
    private IUserService userService;

    @Autowired
    private WxuserMapper wxuserMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ILogininfoService logininfoService;
    @Autowired
    private RedisTemplate redisTemplate;

    /*
    * 通过前端传入的微信授权码，获取令牌，然后通过令牌获取用户信息
    *
    * */
    @GetMapping("/{code}")
    public AjaxResult getAccessToken(@PathVariable("code") String code) throws Exception {
        /*地址*/
        System.out.println(code);
        String url="https://api.weixin.qq.com/sns/oauth2/access_token" +
               "?appid=APPID" +
               "&secret=SECRET" +
               "&code=CODE" +
               "&grant_type=authorization_code";
      /*  替换数据*/
            url=url.replaceAll("APPID",appid)
                    .replaceAll("SECRET",secret)
                    .replaceAll("CODE",code);
        /*发送请求，获取一个字符串，里面包含了令牌accessToken*/
        String result = HttpClientUtils.httpGet(url);
        /*封装一个实体类将上面字符串用JSONObject.parseObject()的方法强转会对象，通过对象.字段名就可以很方便的获取里面的令牌属性access_token和appid*/
        WeChatToken weChatToken = JSONObject.parseObject(result, WeChatToken.class);
        /*获取用户信息的url*/
        String wxUrl="https://api.weixin.qq.com/sns/userinfo?" +
                "access_token=ACCESS_TOKEN" +
                "&openid=OPENID" ;
        /*替换数据，把得到的令牌置入*/
         wxUrl = wxUrl.replaceAll("ACCESS_TOKEN", weChatToken.getAccess_token()).replaceAll("OPENID", weChatToken.getOpenid());
        /*再次发送get请求，获取用户信息,全部包含在accessToken里面*/
         String accessToken = HttpClientUtils.httpGet(wxUrl);
         /*再次封装实体类，用于将上面字符串强转为对象，方便获取里面的字段属性*/
        Wxuser wxuserResult = JSONObject.parseObject(accessToken, Wxuser.class);
        System.out.println(wxuserResult);
        /*注入wxuserMapper，通过appid查询上面对象是否存在*/
        Wxuser PetWxUser= wxuserMapper.selectByOpenid(wxuserResult.getOpenid());
        System.out.println(PetWxUser);
       /*不存在，则直接添加wxuser信息，然后通知用户去绑定*/
        if(PetWxUser==null){
            wxuserMapper.add(wxuserResult);
            /*发送给前端nobingd，让用户去绑定*/
        return AjaxResult.creat().setSuccess(true).setResultObj(wxuserResult.getOpenid()).setMsg("NoBind");
        }
        /*存在*/
        /*判断userid是否为空,告诉用户去绑定*/
        if(PetWxUser.getUserId()==null){
        return AjaxResult.creat().setSuccess(true).setResultObj(wxuserResult.getOpenid()).setMsg("NoBind");
        }
        /*如果都不为空，则直接调用logininfo接口登录*/
        User user = userMapper.loadById(PetWxUser.getUserId());
        LoginVo loginVo = new LoginVo();
        loginVo.setType(BaseConstants.Logininfo.STATE_TYPE_USER);
        loginVo.setUsername(user.getUsername());
        loginVo.setPassword(user.getPassword());
        loginVo.setIsSystem(true);
        AjaxResult ajaxResult = logininfoService.jwtLogin(loginVo);
        return ajaxResult.setMsg("yes");
    }

    /*
    * 获取验证码
    * */

    @PostMapping
    public AjaxResult sendSmS(@RequestBody WxVo wxVo){
            /*校验手机号是否为空*/
            try {
                if(StringUtils.isEmpty(wxVo.getPhone())){
                    return AjaxResult.creat().setSuccess(false).setMsg("手机号不能为空");
                }
            /*判断之前的*/
            Object one = redisTemplate.opsForValue().get(wxVo.getPhone() + BaseConstants.ImgCode.STATE_BIND_CHECK);
                if(one!=null){
                    return AjaxResult.creat().setSuccess(false).setMsg("再点打手");
                }
            /*判断三分钟短信是否过期*/
            Object three = redisTemplate.opsForValue().get(wxVo.getPhone() + BaseConstants.ImgCode.STATE_BIND);
                if(three!=null){
                    /*不为空则重新发送该短信*/
                    System.out.println(three.toString());
                }
            /*校验该手机号是否已经被绑定*/
            User user=  userService.loadByPhone(wxVo.getPhone());
                if(user==null){
                    /*如果手机号没有被注册，则注册该手机号信息，补充数据并保存到数据库*/
                    User newUser = new User();
                    newUser.setPhone(wxVo.getPhone());
                    String salt = StrUtils.getComplexRandomString(32);
                    newUser.setSalt(salt);
                    newUser.setPassword(MD5Utils.encrypByMd5("11111"+salt));
                    newUser.setUsername(wxVo.getPhone());
                    newUser.setCreatetime(new Date());
                    newUser.setState(BaseConstants.User.STATE_USER);
                    userService.add(newUser);
                }else {
                    Wxuser wxuser=wxuserMapper.loadByUserId(user.getId());
                    if(wxuser!=null){
                        return AjaxResult.creat().setSuccess(false).setMsg("该手机号已经被注册");
                    }

                }
            /*生产短信验证码*/
            String code = StrUtils.getRandomString(6);
            /*发送验证短信短信*/
            redisTemplate.opsForValue().set(wxVo.getPhone()+BaseConstants.ImgCode.STATE_BIND,code,3, TimeUnit.MINUTES);
            redisTemplate.opsForValue().set(wxVo.getPhone()+BaseConstants.ImgCode.STATE_BIND_CHECK,"",1, TimeUnit.MINUTES);
            /*发送验证码*/
            System.out.println(code);
            return AjaxResult.creat().setSuccess(true);
        }catch (BusinessException e){
            return AjaxResult.creat().setSuccess(false).setMsg(e.getMessage());
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.creat().setSuccess(false).setMsg("网络故障");
        }
    }
    /* 绑定*/
    @PostMapping("/bind")
    public AjaxResult bindUser(@RequestBody WxVo wxVo){
        try {
            if(StringUtils.isEmpty(wxVo.getPhone())||
                    StringUtils.isEmpty(wxVo.getCode())||
                    StringUtils.isEmpty(wxVo.getOpenid())){
                throw new BusinessException("参数异常");
            }
            Object o = redisTemplate.opsForValue().get(wxVo.getPhone() + BaseConstants.ImgCode.STATE_BIND);
            if(o==null){
                throw new BusinessException("验证码失效");
            }
            System.out.println(o.toString()+"11111111111111");
            System.out.println(wxVo.getCode()+"22222222222");
            if(!o.toString().equals(wxVo.getCode())){
                throw new BusinessException("验证码错误");
            }
            /*做绑定*/
            User user = userMapper.loadByPhone(wxVo.getPhone());
            Wxuser wxuser = wxuserMapper.selectByOpenid(wxVo.getOpenid());
            wxuser.setUserId(user.getId());
            wxuserMapper.update(wxuser);
            /*去登陆*/
            LoginVo loginVo = new LoginVo();
            loginVo.setUsername(user.getUsername());
            loginVo.setPassword(user.getPassword());
            loginVo.setType(BaseConstants.User.STATE_USER);
            loginVo.setIsSystem(true);
            String token = logininfoService.login(loginVo);
            return AjaxResult.creat().setSuccess(true).setResultObj(token);
        }catch (BusinessException e){
            return AjaxResult.creat().setSuccess(false).setMsg(e.getMessage());
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.creat().setSuccess(false).setMsg("网络故障");
        }
    }


}
